package com.medsoft.perfstat.service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cyl.kernel.DBContextHolder;
import com.medsoft.perfstat.dao.ProcDepsSrcDAO;
import com.medsoft.perfstat.pojo.Proc;

@Service
public class ProcDepsService {
	private static final String xx="----";
	private static final String TWO_HTML_SPACE="&nbsp;&nbsp;";
	
	@Autowired
	private ProcDepsSrcDAO procDepsSrcDAO;
	
	public String getDeps(String appname,String db,String name) {
		Map<String,Proc> dep1 = new HashMap<String,Proc>();
		Map<String,Proc> dep2 = new HashMap<String,Proc>();
		Map<String,Proc> dep3 = new HashMap<String,Proc>();
		Map<String,Proc> dep4 = new HashMap<String,Proc>();
		Map<String,Proc> dep5 = new HashMap<String,Proc>();
		Map<String,Proc> dep6 = new HashMap<String,Proc>();
		Map<String,Proc> dep7 = new HashMap<String,Proc>();
		
		DBContextHolder.setTargetDataSource(appname + "_ds");
		dep1.put(db+ "." + name,new Proc(db,name));
		
		queryDeps(dep1,dep2);
		queryDeps(dep2,dep3);
		queryDeps(dep3,dep4);
		queryDeps(dep4,dep5);
		queryDeps(dep5,dep6);
		queryDeps(dep6,dep7);
		
		setProcComment(dep1,dep2,dep3,dep4,dep5,dep6,dep7);
		
		return printDeps(dep1,dep2,dep3,dep4,dep5,dep6,dep7);
	}
	
	private void setProcComment(Map<String, Proc> dep1, Map<String, Proc> dep2,
			Map<String, Proc> dep3, Map<String, Proc> dep4,
			Map<String, Proc> dep5, Map<String, Proc> dep6,
			Map<String, Proc> dep7) {
		for(Proc proc : dep1.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}
		}
		
		for(Proc proc : dep2.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}		
		}
		
		for(Proc proc : dep3.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}
		}
		for(Proc proc : dep4.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}
		}
		for(Proc proc : dep5.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}
		}
		for(Proc proc : dep6.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}
		}
		for(Proc proc : dep7.values()) {
			Proc procR = procDepsSrcDAO.getProc(proc.getDb(), proc.getName());
			if(procR != null) {
				proc.setComment(procR.getComment());
			}
		}
	}

	private String printDeps(Map<String,Proc>dep1,
			Map<String,Proc>dep2,Map<String,Proc> dep3,
			Map<String,Proc>dep4,Map<String,Proc>dep5,
			Map<String,Proc>dep6,Map<String,Proc>dep7) {
		String results = "";
		for(Map.Entry<String, Proc> entry1 : dep1.entrySet()) {
			results = results + TWO_HTML_SPACE + entry1.getKey() + TWO_HTML_SPACE + "--" + entry1.getValue().getComment() + TWO_HTML_SPACE + "<br />" + System.getProperty("line.separator");
			for(Map.Entry<String, Proc> entry2 : dep2.entrySet()) {
				if(entry2.getValue().getParent().equals(entry1.getKey())) {
					results = results + TWO_HTML_SPACE + StringUtils.rightPad(xx, 1*4, '-') + entry2.getKey() + TWO_HTML_SPACE + "--" + entry2.getValue().getComment() + TWO_HTML_SPACE + "<br />" + System.getProperty("line.separator");
					for(Map.Entry<String, Proc> entry3 : dep3.entrySet()) {
						if(entry3.getValue().getParent().equals(entry2.getKey())) {
							results = results + TWO_HTML_SPACE + StringUtils.rightPad(xx, 2*4, '-') + entry3.getKey() + TWO_HTML_SPACE + "--" + entry3.getValue().getComment() + TWO_HTML_SPACE + "<br />" + System.getProperty("line.separator");
							for(Map.Entry<String, Proc> entry4 : dep4.entrySet()) {
								if(entry4.getValue().getParent().equals(entry3.getKey())) {
									results = results + TWO_HTML_SPACE + StringUtils.rightPad(xx, 3*4, '-') + entry4.getKey() + TWO_HTML_SPACE + "--" + entry4.getValue().getComment() + TWO_HTML_SPACE + "<br />" + System.getProperty("line.separator");
									for(Map.Entry<String, Proc> entry5 : dep5.entrySet()) {
										if(entry5.getValue().getParent().equals(entry4.getKey())) {
											results = results + TWO_HTML_SPACE + StringUtils.rightPad(xx, 4*4, '-') + entry5.getKey() + TWO_HTML_SPACE + "--" + entry5.getValue().getComment() + TWO_HTML_SPACE + "<br />" + System.getProperty("line.separator");
											for(Map.Entry<String, Proc> entry6 : dep6.entrySet()) {
												if(entry6.getValue().getParent().equals(entry5.getKey())) {
													results = results + TWO_HTML_SPACE + StringUtils.rightPad(xx, 5*4, '-') + entry6.getKey() + TWO_HTML_SPACE + "--" + entry6.getValue().getComment() + TWO_HTML_SPACE + "<br />" + System.getProperty("line.separator");
													for(Map.Entry<String, Proc> entry7 : dep7.entrySet()) {
														if(entry7.getValue().getParent().equals(entry6.getKey())) {
															results = results + TWO_HTML_SPACE + StringUtils.rightPad(xx, 6*4, '-') + TWO_HTML_SPACE + "--" + entry7.getValue().getComment() + TWO_HTML_SPACE + entry7.getKey() + "<br />" + System.getProperty("line.separator");
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		if(results.equals("")) results = "对象不存在！";
		System.out.println(results);
		return results;
	}

	public Map<String,Proc> queryDeps(Map<String,Proc> procs,Map<String,Proc> depProcs) {
		String procBody = "";
		for(Map.Entry<String, Proc> entry : procs.entrySet()) {
			procBody = procDepsSrcDAO.getProcBody(entry.getValue().getDb(), entry.getValue().getName());
			if(procBody == null) {
				System.out.println(entry.getKey() + "不存在！");
				procs.remove(entry.getKey());
				continue;
			}
			List<String> procBodyLines = Arrays.asList(procBody.toLowerCase().split("\n"));
			String dbProc = "";
			String depDb = "";
			String depProcName = "";
			for(String procBodyLine : procBodyLines) {
				procBodyLine = procBodyLine.replaceAll("`", "");
				if(procBodyLine.indexOf("call ") >= 0) {
					System.out.println("调用" + procBodyLine + "！");
					String[] procBodyWords = procBodyLine.split(" ");
					int i=0;
					for(i=0;i<procBodyWords.length;i++) {
						if(procBodyWords[i].trim().equals("call")) {
							break;
						}
					}
					if(i!=procBodyWords.length-1) {
						dbProc = procBodyWords[i+1];
						System.out.println("调用" + dbProc + "！");
						if(dbProc.indexOf('.')>0) {
							depDb = dbProc.split("\\.")[0];
							depProcName = dbProc.split("\\.")[1];
						} else {
							depDb = entry.getValue().getDb();
							depProcName = dbProc;
						}
						depProcName = depProcName.substring(0, depProcName.indexOf("("));
						if(depDb.equals(entry.getValue().getDb()) && depProcName.equals(entry.getValue().getName())) {
							System.out.println(entry.getKey() + "调用" + depDb + "." + depProcName +", 似乎是递归调用！");
							continue;
						}
						depProcs.put(depDb + "." + depProcName,new Proc(depDb,depProcName,entry.getValue().getDb(),entry.getValue().getName()));
					}
				}
			}
		}
		return depProcs;
	}
	
	public static void main(String[] args) {
		String dbProc = "db_sys.prt_sys_checksysstatus(";
		System.out.println(dbProc.split("\\.").length);
	}
}
